package org.framework.core.override.view;

import java.io.PrintWriter;
import java.util.Map;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.web.servlet.view.json.MappingJacksonJsonView;


public class MappingJacksonJsonpView extends MappingJacksonJsonView {

	/**
	 * Default content type: "application/x-javascript".
	 * Overridable through {@link #setContentType}.
	 */
	public static final String DEFAULT_CONTENT_TYPE = "application/javascript";

	private ObjectMapper objectMapper = new ObjectMapper();
	
	private final String jsonCallback = "_callback";
	
	private String paramCallback;

	
	/**
	 * Construct a new {@code MappingJacksonJsonpView}, setting the content type to {@code application/javascript}.
	 */
	public MappingJacksonJsonpView() {
		setContentType(DEFAULT_CONTENT_TYPE);
		setExposePathVariables(false);
	}

	/**
	 * Specify a custom param name to return call function.
	 * Default is none.
	 * @see #paramCallback
	 */
	public void setParamCallback(String paramCallback) {
		this.paramCallback = paramCallback;
	}

	@Override
	protected void renderMergedOutputModel(Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {

		String callback = request.getParameter(paramCallback);
		
		callback = callback==null?this.jsonCallback:callback;
				
		Object value = filterModel(model);
		String jsonp = callback+"("+objectMapper.writeValueAsString(value)+");";
		
		PrintWriter writer = response.getWriter();
		writer.write(jsonp);
		
		writer.flush();
		writer.close();
	}
}
